<template>
  <div class="ai" @rightBtn="rightBtn" ref="ai" :style="deviceHeight>400 ? {height: this.deviceHeight} : {}">
    
    <scroller class="scroller" ref="scroller" resize="none">
      <div class="wrapper">

        <div 
        v-for="(item) in talkList" 
        :key="item.id" 
        :ref="'msg-'+item.id" >

          <div v-if="item.type == 1" class="item push">
             
             <LImage class="pic pull-pic" :src="Config.img('touxiang.png')" />

             <div class="messages">
              <div v-if="item.state == 0" class="login" :ref="'login-'+item.id"></div>
              <div class="message push-message" 
                @touchstart="onTouchStart(item)" 
                @touchend="onTouchEnd(item)">
                <text style="font-size: 32rpx; line-height: 52rpx;">{{item.content}}</text>
              </div>
             </div>
         </div>
         <div v-else class="item pull">
             
             <LImage class="pic push-pic" :src="Config.img('touxiang_ai.jpg')" />

             <div class="messages">
              <div v-if="item.state == 0" class="login" :ref="'login-'+item.id"></div>
              <div class="message pull-message"
                @touchstart="onTouchStart(item)" 
                @touchend="onTouchEnd(item)"> 
                <text style="font-size: 32rpx; line-height: 52rpx;">{{item.content}}</text>
              </div>
            </div>
         </div>
        </div>
      </div>
		</scroller>

    <div class="bottom">
			
      <input class="bottom-input" 
      type="text" 
      v-model="content" 
      :placeholder="T('请输入聊天内容')"
      placeholder-style="color:#DDD;" 
      :cursor-spacing="6" 
      :disabled="isSend"
      @return="sendClick"
      @focus="onKeyboardShow" 
      @blur="onKeyboardHide">

        <div class="bottom-send no1" v-if="isSend">
          <text class="font32 text1">{{T('发送')}}</text>
        </div>
				<div  v-else class="bottom-send main-bt2" @click="sendClick">
          <text class="font32 text1">{{T('发送')}}</text>
        </div>
		</div>
  </div>
</template>
//你能帮我什么
<style src="@/_css/style.css" ></style>
<style scoped>
  .ai {
    flex: 1;
    display: flex;
    flex-direction: column;
  }
  .scroller {
    display: flex;
    flex-direction: column;
    flex: 1;
  }
  .wrapper {
  }

  /* 消息项，基础类 */
  .item {
      display: flex;
      font-display: row;
      align-items: flex-start;
			padding: 20rpx 20rpx 0 20rpx;
			color: #333;
	}
  .pic {
    width: 92rpx;
    height: 92rpx;
    border-radius: 50%;
    border: #fff solid 1px;
  }
  .messages {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 10rpx;
  }
  .message {
    position: relative;
    word-break: break-all;
    padding: 20rpx;
    border-radius: 8rpx;
    max-width: 500rpx;
  }

  /* 收到的消息 */
  .pull {
    flex-direction: row;
  }
  .pull-pic {
    margin-left : 20rpx;
  }
  .pull-message{
    background-color: #fff;
  }

  /* 发出的消息 */
  .push {
    flex-direction: row-reverse;
  }
  .push-pic {
    margin-right: 20rpx;
  }
  .push-message {
    background-color: #a0e959;
  }

  /** lgoin */
  .login {
    width: 20rpx;
    height: 20rpx;
    border-radius: 50%;
    margin-right: 12rpx;

    border-style: solid;
    border-width: 4rpx;
    border-color: #999;
    border-right-color: #fff;
    transform-origin: center; 
  }

  /******************* 输入框*/
  .bottom {
    flex-shrink: 0;
    z-index: 1;
    position: relative;
    flex-direction: row;
    align-items: center;
    padding-left: 20rpx;
    padding-right: 20rpx;
    padding-top: 20rpx;
    padding-bottom: 20rpx;
    margin-bottom: 60rpx;
    
    border-top-width: 2rpx;
    border-top-color: #222635;
    background: #d72828;
  }
  .bottom-input {
    flex: 1;
    background-color: #fff;
    height: 64rpx;
    padding: 0 20rpx;
    border-radius: 32rpx;
    font-size: 28rpx;
  }
  .bottom-send {
    align-items: center;
    justify-content: center;
    min-width: 120rpx;
    height: 64rpx;
    border-radius: 32rpx;
    
    margin-left: 20rpx;
    padding-left: 32rpx;
    padding-right: 32rpx;
  }
</style>

<script>
  import jconfig from "@/_js/config";
  import jmodal from "@/_js/modal";
  import jdebug from "@/_js/debug";
  import jhttps from "@/_js/https";
  import jnavigator from "@/_js/navigator";
  const clipboard = weex.requireModule("clipboard");

  const animation = weex.requireModule('animation'); //动画
  const domModule = weex.requireModule('dom');
  const stream = weex.requireModule('stream'); //网络请求
  const weexFunction = weex.requireModule("WeexFunction");
  import I18N from "@/_i18n/i18n";
  var T = I18N.t;
  weexFunction.setTitle('AI');
  weexFunction.setRightBtn(T("生成策略"));
  export default {
    components: {},

    data() {
      return {
        Config: jconfig,
        T:T,
				
        isSend: false, //true发送中
				talkList: [], // 聊天列表数据
        content:'', //发送的消息
        
        deviceHeightG: 0,
        deviceHeight: 0,
        timeout: null, //滚动视图时间
        timeoutA: null, //动画时间
        longPressTimer: null // 长按定时器
      };
    },

    created() {
      // setTimeout(() => {
      //   jnavigator.load("", "ai/ai");
      // }, 5000);

    },

    mounted() {
      
      var msgAi = {'content':T('对于量化交易您有什么需要咨询的吗？'), 'type':2, 'state':1, 'ignore':true}
      this.addMsg(msgAi)
      
      setTimeout(()=>{
        domModule.getComponentRect(this.$refs.ai, (result) => {
          if (result && result.result) {
            const height = result.size.height; // 获取高度
            this.deviceHeightG = height
            this.deviceHeight = height
          } else {
            jdebug.log('无法获取界面高度');
          }
        });
      }, 500)
    },

    methods: {


      /** 添加消息
			 * type 1自己，2AI
			 * state 0发送中，1发送完成，-1发送失败
       * ignore true 忽略，不加入发送内容
			 **/
			addMsg(param) {
				
				var {content, type=1, state=0, contentType='text', ignore=false} = param
				
				var pic = type==1 ? '/static/logo.png' : '/static/logo.png'
				
				let msg = {
					"id": new Date().getTime(),
					content, type, state, 
					contentType,
					pic,
          ignore
				}
				this.talkList.push(msg);

        this.scrollTo()
        this.animation(msg)
				return msg
			},

      //动画
      animation(msg) {

        this.$nextTick(() => {
          if(this.timeoutA){
            clearTimeout(this.timeoutA);
          }
          this.timeoutA = setTimeout(() => {
            var ref = this.$refs[`login-${msg.id}`]
            if (msg.state == 0 && ref && ref.length) {
              animation.transition(ref[0], {
                styles: {
                    transform: 'rotate(360000deg)',
                },
                duration: 1000000, //ms
                timingFunction: 'linear',
                needLayout: false,
                delay: 0 //ms
              })
            } else {
              // jdebug.log('ref不存在')
            }
          }, 200);
        })
      },

      // 滚动到最后一条消息
      scrollTo() {
        
        this.$nextTick(() => {
          if(this.timeout){
            clearTimeout(this.timeout);
          }
          this.timeout = setTimeout(() => {
            var msg = this.talkList[this.talkList.length - 1]
            var ref = this.$refs[`msg-${msg.id}`]
            if (ref && ref.length) {
              domModule.scrollToElement(ref[0], 
              {
                'options':0, 
                'animated':true
              })
            }
          }, 200);
        })
      },
      
      /****************************** 输入框*/
      // 键盘弹出时
      onKeyboardShow() {
        this.deviceHeight = this.deviceHeightG / 2
        this.scrollTo()
      },

      onKeyboardHide() {
        this.deviceHeight = this.deviceHeightG 
      },

      /****************************** https*/
			// 发送信息
			httpHandleSend(msg) {

        var msgAi = {'content': '思考中...', 'type':2, 'ignore': true}
				msgAi = this.addMsg(msgAi)


        var messages = [{
          role: 'system',
          content: 'You are a quantitative trading assistant. Provide insights, strategies, and answers related to algorithmic trading and market analysis.',
        }]

        this.talkList.forEach(talk => {
          if(!talk.ignore) {
            messages.push({
              "role": talk.type==1 ? "user" : "assistant",
              "content": talk.content
            })
          }
        });
        jdebug.log(messages)

        var param = {
          "model": "deepseek-reasoner",
          "messages": messages,
          "stream": false
        }
        var options = {
          'method': 'POST',
          'url': 'https://api.deepseek.com/chat/completions',
          'headers': {
            'Authorization': 'Bearer sk-240408b296ce454282cfa3ef4cbad4dc',
            'Content-Type': 'application/json',
            'Accept': 'application/json'
          },
          'type': 'json',
          'body': JSON.stringify(param)
        }
        stream.fetch(options, (res)=>{
          jdebug.log(res)
          this.isSend = false

          var {status,data, error} = res
          if (status == 200) {
            
            var choice = data.choices[0];
            msgAi.state = 1
            msgAi.ignore = false
            msgAi.content =  choice.message.content

            this.talkList.pop();
            this.talkList.push(msgAi)
            this.scrollTo()
          } else {
            try {
              msgAi.content = data.error.message + "：" + status
            } catch (error) {
              try {
                msgAi.content = JSON.stringify(res);//'网络繁忙'
              } catch (error) {
                try {
                  msgAi.content = res;//'网络繁忙'
                } catch (error) {
                  msgAi.content = '网络繁忙'
                }
              }
            }
            msgAi.state = -1
            msg.ignore = true
            this.content = msg.content
            // jmodal.toast(T('发送失败'));
          }
        })

      },

      //https AI生成策略
      httpCreateAiStrategy(){

        jmodal.showLoad()

        var strategyType = 'contract';//Math.random() < 0.7 ? 'spot' : 'contract';
        var param = {strategyType};
        jhttps.post("strategyV3/createAiStrategy",param,true,(data)=>{
          jmodal.hideLoad()
          if(data.status == 200){
            var data = data.data
            var {strategyId, strategyName} = data
            strategyName = strategyName ? strategyName : 'AI'
            var param = {'strategyId':strategyId, 
                        'strategyName':strategyName};
            if (strategyType == 'spot') { 
              jnavigator.open('AI', 'up/SUpAi', param);
            } else {
              jnavigator.open('AI', 'upContract/CUp', param);
            }
          }else{
            jmodal.toast(data.msg);
          }
        });
      },

      /************************** 点击 */
      //导航栏右按钮
      rightBtn() {
        this.httpCreateAiStrategy()
      },

      //发送
      sendClick() {
        if (this.isSend) return
        
        if (!this.content) {
          jmodal.toast(T('请输入聊天内容'));
					return;
				}

				var msg = {'content': this.content, "state":1}
				msg = this.addMsg(msg)

				this.httpHandleSend(msg)
        
        this.isSend = true
        this.content = ''
      }, 
      //消息长按开始 
      onTouchStart(item) {
        this.longPressTimer = setTimeout(() => {
          this.onLongPress(item);
        }, 800); // 长按时间为 800 毫秒 
      },
      //消息长按结束
      onTouchEnd() {
        if (this.longPressTimer) {
          clearTimeout(this.longPressTimer);
          this.longPressTimer = null;
        }
      },

      //长按结束，复制内容
      onLongPress(item) {
        clipboard.setString(item.content);
        jmodal.toast(T("复制成功"));
      }
    }
  };
</script>